package com.cooper.scraper;

import java.util.ArrayList;
import java.util.List;

import com.cooper.android.comm.Resource;

public abstract class ResourceCollector<T extends Resource> {

	protected ResourceScraper<T> scraper;

	protected int pageCount = -1;
	private List<T> medias;
	protected int pageNumber = 1;

	private List<String> removeIds;

	public ResourceCollector() {
		super();
		removeIds = new ArrayList<String>();
	}

	public ResourceCollector(ResourceScraper<T> scraper) {
		this();
		this.scraper = scraper;
	}

	public ResourceCollector(int pageNumber) {
		this();
		this.pageNumber = pageNumber;
	}

	public ResourceCollector(ResourceScraper<T> scraper, int pageNumber) {
		this(pageNumber);
		this.scraper = scraper;
	}

	public ResourceCollector(List<String> removeIds) {
		super();
		this.removeIds = removeIds;
	}

	public ResourceCollector(int pageNumber, List<String> removeIds) {
		super();
		this.pageNumber = pageNumber;
		this.removeIds = removeIds;
	}

	public ResourceCollector(ResourceScraper<T> scraper, int pageNumber,
			List<String> removeIds) {
		this(pageNumber, removeIds);
		this.scraper = scraper;
	}

	public void setScraper(ResourceScraper<T> scraper) {
		this.scraper = scraper;
		reset();
	}

	public boolean BOF() {
		return medias == null;
	}

	public boolean EOF() {
		return (pageCount < pageNumber);
	}

	public boolean hasNextPage() {
		return (pageCount > pageNumber);
	}

	public void nextPage() {
		pageNumber++;
	}

	public int getPageCount() {
		return pageCount;
	}

	protected void setPageCount(int pageCount) {
		if (pageNumber <= pageCount || this.pageCount == -1) {
			this.pageCount = pageCount;
		}
	}

	public List<T> getMedias() {
		return medias;
	}

	protected void setMedias(List<T> medias) {
		this.medias = new ArrayList<T>();
		for (T media : medias) {
			if (!removeIds.contains(media.getId())) {
				this.medias.add(media);
			}
		}
	}

	public int getPageNumber() {
		return pageNumber;
	}

	public void setPageNumber(int pageNumber) {
		this.pageNumber = pageNumber;
	}

	protected void resetMedias() {
		medias = null;
	}

	public void reset() {
		resetMedias();
		pageNumber = 1;
		pageCount = -1;
	}

	public boolean noResult() {
		if (medias == null) {
			throw new IllegalStateException("not call download yet");
		} else {
			return medias.isEmpty() && !hasNextPage();
		}
	}

	public abstract String generateKey();

	public abstract ResultUrl scraperListUrl() throws ScraperException,
			DownloadException;

	public abstract void scraperResult(String page, String referer)
			throws ScraperException, DownloadException;

	public abstract void scraperResult(String page, String referer,
			String redirectUrl) throws ScraperException, DownloadException;

	public abstract boolean subscribed(String key);

}
